package edu.pitt.dbmi.odie.gapp.gwt.server.user;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.logging.Logger;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gdata.client.http.AuthSubUtil;
import com.google.gdata.util.AuthenticationException;

import edu.pitt.dbmi.odie.gapp.gwt.server.util.gdata.ODIE_DocsServiceFetcher;

@SuppressWarnings("serial")
public class ODIE_LoginInServlet extends HttpServlet {

	private static final Logger log = Logger.getLogger(ODIE_LoginInServlet.class
			.getName());

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		log.info("Called with ODIE_SignInServlet queryString is "
				+ req.getQueryString());
		cacheServerSideLoginInfoFromQueryString(req) ;
		resp.sendRedirect(ODIE_UserUtils.reDirectToOdieClient(req, resp));
	}
	
	private void propogateRequestHandler(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		log.info("Called with ODIE_SignInServlet queryString is "
				+ req.getQueryString());
		
		String nextUrl = propogateRequest(req) ;
		if (nextUrl == null) {
			nextUrl = ODIE_UserUtils.reDirectToOdieClient(req, resp);
		}
		log.info("ODIE_SignInServlet: redirecting to " + nextUrl) ;
		
		resp.sendRedirect(nextUrl);
	}

	private String propogateRequest(HttpServletRequest req) {
		String authSubUrl = null ;
		cacheServerSideLoginInfoFromQueryString(req) ;
		String nextUrl = ODIE_UserUtils.assembleRequestUri(req) + "/"
		+ "odie_client/authz_gdocs";
		String scope = "http://docs.google.com/feeds/";
		boolean secure = false;
		boolean session = true;
		authSubUrl = AuthSubUtil.getRequestUrl("webodie.net", nextUrl, scope, secure, session) ;
		return authSubUrl ;
	}
	
	private void cacheServerSideLoginInfoFromQueryString(HttpServletRequest req) {
		
		ODIE_ServerSideLoginInfo loginInfo = new ODIE_ServerSideLoginInfo() ;
		
		UserService userService = UserServiceFactory.getUserService();
		User user = userService.getCurrentUser();
		
		String authSubToken = AuthSubUtil.getTokenFromReply(req
				.getQueryString());
		log
				.info("ODIE_SignInServlet establishing from mechanism init authSubToken = "
						+ authSubToken);
		String authSubSessionToken = exchangeForAuthSubSessionToken(
				authSubToken, null);
		log
				.info("ODIE_SignInServlet exchanged for authSubSessionToken = "
						+ authSubSessionToken);
		if (user != null) {
			loginInfo.setEmailAddress(user.getEmail()) ;
			loginInfo.setNickName(user.getNickname()) ;
		}
		else {
			loginInfo.setEmailAddress("UNDEFINED") ;
			loginInfo.setNickName("UNDEFINED") ;
		}
		
		loginInfo.setAuthSubToken(authSubToken) ;
		loginInfo.setAuthSubSessionToken(authSubSessionToken) ;
		
		ODIE_UserUtils.establishSessionCache(this, loginInfo) ;
		
		this.getServletContext().setAttribute(loginInfo.getClass().getName(), loginInfo) ;
		
	}
	
	private String exchangeForAuthSubSessionToken(String authSubToken,
			String domain) {
		String authSubSessionToken = null;
		try {
			if (authSubToken != null) {
				if (domain != null) {
					authSubSessionToken = AuthSubUtil.exchangeForSessionToken(
							"http", domain, authSubToken, null);
				} else {
					authSubSessionToken = AuthSubUtil.exchangeForSessionToken(
							authSubToken, null);
				}
			}
		} catch (AuthenticationException e) {
			;
		} catch (IOException e) {
			;
		} catch (GeneralSecurityException e) {
			;
		}
		return authSubSessionToken;
	}
	
	private void initializeFromWebXml(String authSubToken) {
		log
				.info("ODIE_SignInServlet establishing from web.xml init authSubSessionToken = "
						+ authSubToken);
		establishSessionCache(this, authSubToken);
	}

	private void consumeRequest(HttpServletRequest req, HttpServletResponse resp) {
		try {
			log.info("Called with ODIE_SignInServlet queryString is "
					+ req.getQueryString());
			String reDirectUrl = ODIE_UserUtils.reDirectToOdieClient(req, resp);
			String authSubToken = getInitParameter("sessionToken");
			if (authSubToken != null) {
				log
						.info("ODIE_SignInServlet establishing from web.xml init authSubSessionToken = "
								+ authSubToken);
				establishSessionCache(this, authSubToken);
			} else {
				authSubToken = AuthSubUtil.getTokenFromReply(req
						.getQueryString());
				log
						.info("ODIE_SignInServlet establishing from mechanism init authSubToken = "
								+ authSubToken);
				String authSubSessionToken = ODIE_UserUtils
						.exchangeForAuthSubSessionToken(authSubToken);
				log
						.info("ODIE_SignInServlet exchagned for authSubSessionToken = "
								+ authSubSessionToken);
				UserService userService = UserServiceFactory.getUserService();
				User user = userService.getCurrentUser();
				if (user != null) {
					log.info("ODIE_AuthzGDocsServlet found user "
							+ user.getEmail());
					ODIE_UserUtils.establishSessionCache(this, user,
							authSubToken, authSubSessionToken);
				} else {
					establishSessionCache(this, authSubSessionToken);
				}
			}
			resp.sendRedirect(reDirectUrl);
		} catch (IOException e) {
			log.info("ODIE_SignInServlet: fails with " + e.getMessage());
		}
	}

	private void establishSessionCache(HttpServlet httpServlet,
			String authSubSessionToken) {
		ODIE_ServerSideLoginInfo serverSideLoginInfo = new ODIE_ServerSideLoginInfo();
		serverSideLoginInfo.setAuthSubSessionToken(authSubSessionToken);
		ODIE_DocsServiceFetcher.fetchOrCreateDocsService(httpServlet,
				serverSideLoginInfo);
	}

	private String createLoginURL2(HttpServletRequest req) {
		String nextUrl = ODIE_UserUtils.assembleRequestUri(req) + "/"
				+ "odie_client/authz_gdocs";
		String scope = "http://docs.google.com/feeds/";
		boolean secure = false; // set secure=true to request secure
		// AuthSub
		// tokens
		boolean session = true;
		String authzGDocsUrl = AuthSubUtil.getRequestUrl("webodie.net",
				nextUrl, scope, secure, session);
		log.info("ODIE_SignInServlet authzGDocsUrl ==> " + authzGDocsUrl);
		return authzGDocsUrl;
	}

}
